package com.christina.engine.factory.impl;

import com.christina.engine.factory.ServiceExecutorFactory;
import com.christina.engine.execution.ServiceExecutor;
import com.christina.engine.execution.impl.ChatServiceExecutor;
import com.christina.engine.execution.impl.TravelServiceExecutor;
import com.christina.engine.execution.impl.UserServiceExecutor;
import com.christina.service.domain.chat.ChatDomainService;
import com.christina.service.domain.travel.TravelDomainService;
import com.christina.service.domain.user.UserDomainService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 默认服务执行器工厂实现
 * 负责创建和管理各种服务执行器
 * 
 * @author Christina
 */
@Slf4j
@Component
public class DefaultServiceExecutorFactory implements ServiceExecutorFactory {
    
    private final ApplicationContext applicationContext;
    private final Map<String, ExecutorCreator> executorCreators = new ConcurrentHashMap<>();
    private final Map<Class<?>, String> serviceTypeMapping = new ConcurrentHashMap<>();
    
    @Autowired
    public DefaultServiceExecutorFactory(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
        initializeDefaultCreators();
    }
    
    /**
     * 初始化默认的执行器创建器
     */
    private void initializeDefaultCreators() {
        // 注册聊天服务执行器
        registerExecutorCreator("ChatDomainService", () -> {
            ChatDomainService chatService = applicationContext.getBean(ChatDomainService.class);
            return new ChatServiceExecutor(chatService);
        });
        
        // 注册出行服务执行器
        registerExecutorCreator("TravelDomainService", () -> {
            TravelDomainService travelService = applicationContext.getBean(TravelDomainService.class);
            return new TravelServiceExecutor(travelService);
        });
        
        // 注册用户服务执行器
        registerExecutorCreator("UserDomainService", () -> {
            UserDomainService userService = applicationContext.getBean(UserDomainService.class);
            return new UserServiceExecutor(userService);
        });
        
        // 注册服务类型映射
        serviceTypeMapping.put(ChatDomainService.class, "ChatDomainService");
        serviceTypeMapping.put(TravelDomainService.class, "TravelDomainService");
        serviceTypeMapping.put(UserDomainService.class, "UserDomainService");
        
        // 注册别名
        registerAlias("chat", "ChatDomainService");
        registerAlias("travel", "TravelDomainService");
        registerAlias("user", "UserDomainService");
        
        log.info("Initialized default service executor factory with {} creators", executorCreators.size());
    }
    
    /**
     * 注册服务别名
     * 
     * @param alias 别名
     * @param serviceName 实际服务名称
     */
    private void registerAlias(String alias, String serviceName) {
        ExecutorCreator creator = executorCreators.get(serviceName);
        if (creator != null) {
            executorCreators.put(alias, creator);
        }
    }
    
    @Override
    public ServiceExecutor createExecutor(String serviceName) {
        if (serviceName == null || serviceName.trim().isEmpty()) {
            throw new IllegalArgumentException("Service name cannot be null or empty");
        }
        
        ExecutorCreator creator = executorCreators.get(serviceName);
        if (creator == null) {
            // 尝试查找模糊匹配
            creator = findFuzzyMatch(serviceName);
        }
        
        if (creator == null) {
            throw new IllegalArgumentException("No executor creator found for service: " + serviceName);
        }
        
        try {
            ServiceExecutor executor = creator.create();
            log.debug("Created executor for service: {}", serviceName);
            return executor;
        } catch (Exception e) {
            log.error("Failed to create executor for service: {}", serviceName, e);
            throw new RuntimeException("Failed to create executor for service: " + serviceName, e);
        }
    }
    
    @Override
    public ServiceExecutor createExecutor(Class<?> serviceType) {
        if (serviceType == null) {
            throw new IllegalArgumentException("Service type cannot be null");
        }
        
        String serviceName = serviceTypeMapping.get(serviceType);
        if (serviceName == null) {
            // 尝试根据类名推断服务名称
            serviceName = inferServiceNameFromType(serviceType);
        }
        
        if (serviceName == null) {
            throw new IllegalArgumentException("No executor creator found for service type: " + serviceType.getName());
        }
        
        return createExecutor(serviceName);
    }
    
    /**
     * 查找模糊匹配的创建器
     * 
     * @param serviceName 服务名称
     * @return 执行器创建器，如果没有找到返回null
     */
    private ExecutorCreator findFuzzyMatch(String serviceName) {
        String lowerServiceName = serviceName.toLowerCase();
        
        // 检查是否包含关键词
        for (String registeredName : executorCreators.keySet()) {
            String lowerRegisteredName = registeredName.toLowerCase();
            
            if (lowerRegisteredName.contains(lowerServiceName) || 
                lowerServiceName.contains(lowerRegisteredName)) {
                log.debug("Found fuzzy match: {} -> {}", serviceName, registeredName);
                return executorCreators.get(registeredName);
            }
        }
        
        return null;
    }
    
    /**
     * 根据服务类型推断服务名称
     * 
     * @param serviceType 服务类型
     * @return 推断的服务名称，如果无法推断返回null
     */
    private String inferServiceNameFromType(Class<?> serviceType) {
        String className = serviceType.getSimpleName();
        
        // 尝试直接匹配类名
        if (executorCreators.containsKey(className)) {
            return className;
        }
        
        // 尝试匹配包含类名关键词的服务
        String lowerClassName = className.toLowerCase();
        for (String serviceName : executorCreators.keySet()) {
            if (serviceName.toLowerCase().contains(lowerClassName) ||
                lowerClassName.contains(serviceName.toLowerCase())) {
                return serviceName;
            }
        }
        
        return null;
    }
    
    @Override
    public boolean supportsService(String serviceName) {
        if (serviceName == null || serviceName.trim().isEmpty()) {
            return false;
        }
        
        return executorCreators.containsKey(serviceName) || findFuzzyMatch(serviceName) != null;
    }
    
    @Override
    public boolean supportsService(Class<?> serviceType) {
        if (serviceType == null) {
            return false;
        }
        
        return serviceTypeMapping.containsKey(serviceType) || 
               inferServiceNameFromType(serviceType) != null;
    }
    
    @Override
    public Set<String> getSupportedServiceNames() {
        return new HashSet<>(executorCreators.keySet());
    }
    
    @Override
    public Set<Class<?>> getSupportedServiceTypes() {
        return new HashSet<>(serviceTypeMapping.keySet());
    }
    
    @Override
    public void registerExecutorCreator(String serviceName, ExecutorCreator executorCreator) {
        if (serviceName == null || serviceName.trim().isEmpty()) {
            throw new IllegalArgumentException("Service name cannot be null or empty");
        }
        
        if (executorCreator == null) {
            throw new IllegalArgumentException("Executor creator cannot be null");
        }
        
        executorCreators.put(serviceName, executorCreator);
        log.info("Registered executor creator for service: {}", serviceName);
    }
    
    @Override
    public void unregisterExecutorCreator(String serviceName) {
        ExecutorCreator removed = executorCreators.remove(serviceName);
        if (removed != null) {
            log.info("Unregistered executor creator for service: {}", serviceName);
        }
    }
    
    /**
     * 注册服务类型映射
     * 
     * @param serviceType 服务类型
     * @param serviceName 服务名称
     */
    public void registerServiceTypeMapping(Class<?> serviceType, String serviceName) {
        if (serviceType == null) {
            throw new IllegalArgumentException("Service type cannot be null");
        }
        
        if (serviceName == null || serviceName.trim().isEmpty()) {
            throw new IllegalArgumentException("Service name cannot be null or empty");
        }
        
        serviceTypeMapping.put(serviceType, serviceName);
        log.info("Registered service type mapping: {} -> {}", serviceType.getSimpleName(), serviceName);
    }
    
    /**
     * 注销服务类型映射
     * 
     * @param serviceType 服务类型
     */
    public void unregisterServiceTypeMapping(Class<?> serviceType) {
        String removed = serviceTypeMapping.remove(serviceType);
        if (removed != null) {
            log.info("Unregistered service type mapping for: {}", serviceType.getSimpleName());
        }
    }
    
    /**
     * 批量创建执行器
     * 
     * @param serviceNames 服务名称列表
     * @return 执行器映射
     */
    public Map<String, ServiceExecutor> createExecutors(String... serviceNames) {
        Map<String, ServiceExecutor> executors = new HashMap<>();
        
        for (String serviceName : serviceNames) {
            try {
                ServiceExecutor executor = createExecutor(serviceName);
                executors.put(serviceName, executor);
            } catch (Exception e) {
                log.warn("Failed to create executor for service: {}", serviceName, e);
            }
        }
        
        return executors;
    }
    
    /**
     * 创建所有支持的执行器
     * 
     * @return 执行器映射
     */
    public Map<String, ServiceExecutor> createAllExecutors() {
        Map<String, ServiceExecutor> executors = new HashMap<>();
        
        // 只创建主要服务的执行器，避免重复创建别名
        Set<String> mainServices = Set.of("ChatDomainService", "TravelDomainService", "UserDomainService");
        
        for (String serviceName : mainServices) {
            if (executorCreators.containsKey(serviceName)) {
                try {
                    ServiceExecutor executor = createExecutor(serviceName);
                    executors.put(serviceName, executor);
                } catch (Exception e) {
                    log.warn("Failed to create executor for service: {}", serviceName, e);
                }
            }
        }
        
        return executors;
    }
    
    /**
     * 获取工厂统计信息
     * 
     * @return 统计信息
     */
    public Map<String, Object> getFactoryStatistics() {
        Map<String, Object> stats = new HashMap<>();
        stats.put("totalCreators", executorCreators.size());
        stats.put("supportedServices", getSupportedServiceNames());
        stats.put("supportedTypes", getSupportedServiceTypes().stream()
                .map(Class::getSimpleName)
                .collect(java.util.stream.Collectors.toSet()));
        stats.put("typeMappings", serviceTypeMapping.size());
        
        return stats;
    }
    
    /**
     * 清空所有注册的创建器
     */
    public void clearAll() {
        executorCreators.clear();
        serviceTypeMapping.clear();
        log.info("Cleared all executor creators and type mappings");
    }
    
    /**
     * 重新初始化默认创建器
     */
    public void reinitialize() {
        clearAll();
        initializeDefaultCreators();
        log.info("Reinitialized service executor factory");
    }
}